在ASP.NET中沒有內建的分頁控制項,但可以從GridView屬性的AllowPaging設定為True,就可以完成分頁,但使用內建的分頁功能,資料量小的話還好,若資料量大的話,效能會變得很不好,原因是GridView內建的是一次從資料庫取得所有資料,若資料量一大讀取速度就會變慢,而且GridView的AllowPaging我也沒研究過,之後再研究看看XD
然後其實在ASP.NET中可以自製一個控制項,使用方法就是建立一個「Web Forms使用者控制項」。並將HTML、CSS等寫到裡面,就可以完成一個自製的控制項,拖曳到自己的Web頁面就可以使用了。
使用自製控制項的話,就可以想顯示幾筆資料就跟資料庫要幾筆資料就好(使用CTE和ROW_NUMBER()),總資料量大也沒關係的,跟GridView內建的分頁功能相比,效能相對比較好。
現在已有一個GridView已經與資料庫取得資料了,並且顯示,資料表叫做[ORID_data],不過由於資料料很多,我們需要有分頁,讓使用者體驗可以比較好,頁面也比較乾淨整齊。
今天要使用一個現成的分頁控制項,並且讓它可以與SQL SERVER連接,在網頁上正常使用。
那就開始ㄅ
我們先創一個「Web Forms使用者控制項」其名為GridView_Page1。
建立後,從工具箱拉一個Literal控制項到GridView_Page1.ascx,並替ID命名為litpage1。
Literal控制項之後寫會員權限分配管理時在作介紹囉XD
寫入分頁的HTML程式碼。
然後創一個CSS樣式表,貼上寫好的分頁CSS,並在GridView_Page1.ascx控制項內link CSS。
完成分頁的控制項後,就可以直接當成工具,用拖曳的方式拉到需要分頁功能的aspx頁面上,我將它放在GridView控制項的下方。
通常分頁控制項要填寫的會有三個參數
1.每頁顯示的資料數量
2.資料總數量
3.分頁的網址參數(ex:第二頁就是aspx?page=2)
假設現在分頁控制項要填入的參數如下:
那麼首先先limit及totalitems先隨便填入一個值,然後呼叫此副程式,先測試看看是否有分頁出現。
public void Pagination()
{
//每頁數量
GridView_Page1.limit = 3;
//資料總量
GridView_Page1.totalitems = 300;
//連結文字,例:pagination.aspx?page=foo=bar
GridView_Page1.targetpage = "orid_main.aspx";
//顯示分頁控制項
GridView_Page1.showPageControls();
}
分頁有成功出現,且也按照設定出現共300筆資料及100頁。
然後注意到網址,剛進入頁面時。
按下第5頁時。
從上圖會發現一開始在第一頁時,網址的參數並不會有Page=1。
所以先在Page_Load建立一個存網址是第幾頁的變數,使用三元運算子,假如是NULL就是1,不然就看第幾頁就是第幾頁。
int page = Request["page"]==null?1: Convert.ToInt32(Request["page"]);
現在需要抓到資料庫內真正的資料總數量,並交給totalitems輸入,需使用DataReader或DataSet(DataTable)來取得資料,並放在totalitems的值。
使用DataTable的方式,SQL使用COUNT()來取得總筆數:
//取得與資料庫的聯繫
string getconfig = System.Web.Configuration.WebConfigurationManager
.ConnectionStrings["ConnectionStrings的NAME"].ConnectionString;
//建立與資料庫的通道
SqlConnection getConnection = new SqlConnection(getconfig);
//下取得總數量的SQL語法
SqlCommand command = new SqlCommand($"SELECT count(*) FROM ORID_data ", getConnection);
//取得資料庫資料
SqlDataAdapter loginAdapter = new SqlDataAdapter(command);
//創立準備存放資料的記憶體資料集
DataTable user = new DataTable();
//將取得的資料存入記憶體資料集中
loginAdapter.Fill(user);
totalitems(總筆量)就可以放上取得的資料總筆數。
GridView_Page1.totalitems = Convert.ToInt32(user.Rows[0][0]);
假設我想每頁顯示16筆資料。GridView_Page1.limit = 16;
切換分頁時要讓GridView上的資料會跟著分頁做變化,那麼就需要使用到SQL中暫存的CTE及ROW_NUMBER()的排序方法。
先在SQL Server中測試看看是否抓的到資料
with cte as (select ROW_NUMBER() OVER (ORDER BY id ASC) as ROW_ID ,* from ORID_data )
select * from cte where ROW_ID >= 1 and ROW_ID <=16
顯示結果只會出現ROW_ID範圍內16筆資料
那麼現在只需要將ROW_ID的範圍改成網址上的page參數分頁公式就可以成功在每個分頁抓到需要顯示的資料。
ROW_ID >= [分頁中的第一筆] and ROW_ID <= [分頁中的最後一筆]
還記得在上面抓取每分頁網址上的參數時,我們有設一個參數取得網址的page參數ㄇ,原因是假設按到第二分頁時page=2 ;第三分頁page=3以此類推。
int page = Request["page"]==null?1: Convert.ToInt32(Request["page"]);
公式如下:
ROW_ID >= [分頁中的第一筆] and ROW_ID <= [分頁中的最後一筆]
條件:每頁顯示16筆,所以
第一頁的第一筆是 1 ;第一頁的最後一筆是16
第二頁的第一筆是 17 ;第二頁的最後一筆是32
分頁的變數是 page
可得知:
[分頁中的第一筆]= (page-1) * [每頁顯示的筆數]+1
[分頁中的最後一筆]= page * [每頁顯示的筆數]
所以SQL語法就可以寫:
with cte as (select ROW_NUMBER() OVER (ORDER BY id ASC) as ROW_ID ,* from ORID_data )
select * from cte where ROW_ID >= **(page-1) * 16+1** and ROW_ID <= **page*16**
讓GridView取得資料並顯示,如下:
//取得網址參數
int page = Request["page"] == null ? 1 : Convert.ToInt32(Request["page"]);
//與資料庫的連接
string config = System.Web.Configuration.WebConfigurationManager
.ConnectionStrings["ORIDConnectionString"].ConnectionString;
//建立與資料庫的通道
SqlConnection connection = new SqlConnection(config);
//SQL語法
SqlCommand command = new SqlCommand($"with cte as (select ROW_NUMBER() OVER (ORDER BY id ASC) as ROW_ID ,* from ORID_data )\r\n\r\nselect * from cte where ROW_ID >= {(page-1) * 16+1} and ROW_ID <= {page*16} ", connection);
//使用DataTable
//取得資料庫資料
SqlDataAdapter Adapter = new SqlDataAdapter(command);
//創立準備存放資料的記憶體資料集
DataTable user = new DataTable();
//將取得的資料存入記憶體資料集中
Adapter.Fill(user);
//控制項的資料來源是從user記憶體資料集
GridView1.DataSource = user;
//資料與控制項繫結
GridView1.DataBind();
運用使用者控制項達成分頁的功能,484比想像中來得簡單,比較麻煩的應該是要做出自製的分頁控制項XDD